﻿namespace SPWikiProvisioning.Receivers
{
    #region Usings

    using System.Collections;
    using System.Xml;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Utilities;
    using SPWikiProvisioning.Extensions;
    using SPWikiProvisioning.Helpers;
    using SPWikiProvisioning.Model;

    #endregion

    public class WikiPagesProvisioningReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            var web = properties.Feature.GetRelatedSPWeb();
            var pagesList = web.GetPagesList();
            var data = GetProvisioningInformation(properties);

            var document = new XmlDocument();
            document.LoadXml(FeatureHelper.ParseProvisioningProperties(data, web.Language));

            var xmlPages = document.SelectNodes(@"/WikiPages/WikiPage");

            if (xmlPages != null)
            {
                var oldAllowUnsafeUpdates = web.AllowUnsafeUpdates;
                web.AllowUnsafeUpdates = true;
                foreach (XmlNode xmlPage in xmlPages)
                {
                    ProvisionWikiPage(web, pagesList, xmlPage);
                }
                web.AllowUnsafeUpdates = oldAllowUnsafeUpdates;
            }

            web.Update();
        }

        private string GetProvisioningInformation(SPFeatureReceiverProperties properties)
        {
            SPFeaturePropertyCollection featureProperties = properties.Feature.Properties;
            string provisioningFileName = featureProperties["ProvisioningFileName"] != null ? featureProperties["ProvisioningFileName"].Value : "ProvisionedElements.xml";
            return properties.Feature.GetFeatureDefinitionFileContents(provisioningFileName);
        }

        private static void ProvisionWikiPage(SPWeb web, SPList pagesList, XmlNode xmlPage)
        {
            var selectSingleNode = xmlPage.SelectSingleNode("./Title");
            if (selectSingleNode == null)
            {
                return;
            }
            var name = selectSingleNode.InnerText;
            var isDefault = GetProvisionedPageIsDefault(xmlPage);

            var webparts = xmlPage.SelectNodes(@"./WebParts/WebPart");

            var webPartsCollection = new Hashtable();

            if (webparts != null)
            {
                foreach (XmlNode webpart in webparts)
                {
                    ProvisionWebPart(webPartsCollection, webpart);
                }
            }

            string url = string.Format("{0}/{1}.aspx", pagesList.RootFolder.ServerRelativeUrl, name);
            var pageContent = string.Empty;
            var wikiFieldNode = xmlPage.SelectSingleNode("./WikiField");
            if (wikiFieldNode != null) pageContent = wikiFieldNode.InnerText;

            SPFile file = web.GetFile(url);
            if (!file.Exists)
            {
                file = SPUtility.CreateNewWikiPage(pagesList, url);
            }

            file.ProvisionWikiPage(pageContent, webPartsCollection, isDefault);
        }

        private static void ProvisionWebPart(Hashtable webPartsCollection, XmlNode webpart)
        {
            var provisionedWebPart = new ProvisionedWebPart();
            var xmlNode = webpart.SelectSingleNode("./WebPartID");
            if (xmlNode != null)
            {
                provisionedWebPart.WebPartId = xmlNode.InnerText;
                var node = webpart.SelectSingleNode("./WebPartContent");
                if (node != null)
                {
                    provisionedWebPart.WebPartContent = node.InnerText;
                }

                node = webpart.SelectSingleNode("./TargetAudience");
                if (node != null)
                {
                    provisionedWebPart.WebPartAudience = node.InnerText;
                }

                webPartsCollection.Add(provisionedWebPart.WebPartId, provisionedWebPart);
            }
        }

        private static bool GetProvisionedPageIsDefault(XmlNode xmlPage)
        {
            var isDefault = false;
            var singleNode = xmlPage.SelectSingleNode("./Default");
            if (singleNode != null)
            {
                isDefault = bool.Parse(singleNode.InnerText);
            }

            return isDefault;
        }
    }
}
